package tech.dongling.boot.common.parser;

import cn.hutool.core.util.IdUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import tech.dongling.boot.common.base.ApiResponse;
import tech.dongling.boot.common.base.HttpBizRequest;
import tech.dongling.boot.anno.HttpProcessor;
import tech.dongling.boot.ioc.LightIocContainer;
import tech.dongling.boot.plugins.PluginManager;

import java.util.Properties;

// HTTP处理器
public class HttpProtocolHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    private static final Logger logger = LoggerFactory.getLogger(HttpProtocolHandler.class);

    private final LightIocContainer ioc;
    private final PluginManager pluginManager;

    public HttpProtocolHandler(LightIocContainer ioc, Properties config) {
        this.ioc = ioc;
        this.pluginManager = new PluginManager(config);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
        ApiResponse response = new ApiResponse();
        try {
            // 生成请求ID并设置到MDC
            MDC.put("requestId", IdUtil.fastSimpleUUID());
            logger.info("Received request: {} {}", request.method(), request.uri());
            // 限流检查
            if (pluginManager.getLimiter() != null && !pluginManager.getLimiter().tryAcquire()) {
                logger.warn("Request rejected due to rate limiting");
                response.setCode(429);
                response.setMsg("请求频繁");
                sendResponse(ctx, response);
                return;
            }

            // 解析请求
            HttpBizRequest bizReq = HttpReqParser.parse(request);
            logger.debug("Parsed request path: {}", bizReq.getPath());
            // 执行请求插件链
            pluginManager.executeRequestPlugins(bizReq);

            // 业务处理
            HttpProcessor processor = (HttpProcessor) ioc.getProtocolHandler(bizReq.getPath());
            if (processor != null) {
                logger.debug("Found processor for path: {}", bizReq.getPath());
                response.setCode(200);
                response.setData(processor.handle(bizReq));
                logger.info("Request processed successfully");
            } else {
                logger.warn("No processor found for path: {}", bizReq.getPath());
                response.setCode(404);
                response.setMsg("路径不存在");
            }
        } catch (Exception e) {
            logger.error("Error processing request: {}", e.getMessage(), e);
            response.setCode(500);
            response.setMsg(e.getMessage());
        }
        try {
            // 执行响应插件链
            pluginManager.executeResponsePlugins(response);
        } catch (Exception e) {
            response.setCode(500);
            response.setMsg("响应处理失败");
        }
        sendResponse(ctx, response);

        // 清理MDC
        MDC.clear();
    }

    private void sendResponse(ChannelHandlerContext ctx, ApiResponse response) {
        FullHttpResponse httpResp = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
                Unpooled.wrappedBuffer(response.toJsonBytes())
        );
        httpResp.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json;charset=utf-8");
        ctx.writeAndFlush(httpResp);
        logger.debug("Response sent with code: {}", response.getCode());
    }
}